/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.knolle.proveedorServicios;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.hibernate.criterion.*;
import org.marcelo.agro.entidades.*;
import org.marcelo.agro.core.api.ITotales;
import org.marcelo.agro.entidades.noadministrados.Estadisticas;
import org.marcelo.comun.notificaciones.Notificaciones;
import org.openide.util.lookup.ServiceProvider;

/**
 *
 * @author marcelo
 */

@ServiceProvider(service = ITotales.class)
public class TotalesDatabase extends ActividadesDatabase implements ITotales{

    /*
     * Codigo a ser reutilizado
     */
     private static final ProjectionList listaDeProyecciones = Projections.projectionList()
                .add(Projections.count("id").as("count") )
                .add(Projections.sum("total").as("sum"))
                .add(Projections.avg("total").as("avg"))
                .add(Projections.max("total").as("max"))
                .add(Projections.min("total").as("min"));
//                .add(Projections.groupProperty("campanas").as("campoAgrupamiento"));
    
    
    @Override
    public List<Actividades> getAll()  {
        return super.getAll(Actividades.class);
    }

    @Override
    public List<Actividades> getFilteredActividades(Campanas campanias, Lotes lote)  {
        
            return getFilteredObjects(Actividades.class, 
                Arrays.asList(
                   Restrictions.eq("campanas", campanias),
                   Restrictions.eq("lotes", lote)
                ), 
                Order.asc("campanas"),Order.asc("lotes"),Order.asc("tipoActividad"),Order.asc("tipoProducto") );
        
    }

    @Override
    public List<Actividades> getFilteredActividades(Lotes lote)  {
        
            return getFilteredObjects(Actividades.class, 
                Arrays.asList(
                   Restrictions.eq("lotes", lote),
                   Restrictions.disjunction()
                ), 
                Order.asc("id"));
        
        
    }

    @Override
    public List<Actividades> getFilteredActividades(Campanas campania)  {
        return getFilteredObjects(Actividades.class, 
                Arrays.asList(
                   Restrictions.eq("campanas", campania)
                ), 
                Order.asc("campanas"),Order.asc("lotes"),Order.asc("tipoActividad"),Order.asc("tipoProducto") );
    }

    @Override
    public List<TipoActividad> getFilteredTipoActividad(Lotes lote)  {
        
        List<Actividades>  actividadesList =  getFilteredActividades(lote);
        if (actividadesList != null ){
            List<TipoActividad> tipoActividadList = new ArrayList<TipoActividad>();
            for (Actividades act: actividadesList ) {
                tipoActividadList.add(act.getTipoActividad());
            }
            return tipoActividadList;
        }
        return new ArrayList<TipoActividad>();
    }

    /**
     * Este metodo esta mal, debe retornar solo los tipos de actividades que no sean repetidos
     * @param campania
     * @param lote
     * @return 
     */
    @Override
    public List<TipoActividad> getFilteredTipoActividad(Campanas campania, Lotes lote) {
        
        String hqlQuery = "From TipoActividad as ta where ta.id in "
                + "( select act.tipoActividad.id from Actividades as act where act.campanas.id =   "
                + campania.getId() + "and act.lotes.id =  " + lote.getId()
                + ") ";
//        try {
            return getListEnBaseACriterio(hqlQuery);
//        }
//        catch (Exception e) {
//             String errorEn="getFilteredTipoActividad(Campanas campania, Lotes lote) :\n";
//            Notificaciones.notificar(MENSAJE_ERROR_CONSULTA, errorEn+ e.toString());
//        }
//        return new ArrayList<TipoActividad>();

    }

    @Override
    public List<TipoActividad> getFilteredTipoActividad(Campanas campania) {
        String hqlQuery = "from TipoProducto tp where tp.id  in "
                + "( select ac.tipoActividad.id from Actividades as ac where ac.campanas.id = )"
                + campania.getId();
//        try {
            return getListEnBaseACriterio(hqlQuery);
//        }
//        catch (Exception e) {
//             String errorEn="getFilteredTipoActividad(Campanas campania) :\n";
//            Notificaciones.notificar(MENSAJE_ERROR_CONSULTA, errorEn+ e.toString());
//        }
//        return new ArrayList<TipoActividad>();
    }

    @Override
    public List<TipoProducto> getFilteredTipoProducto(Campanas campania, Lotes lote, TipoActividad tipoActividad) {
       String hqlQuery = "from TipoProducto tp where tp.id in (select ac.tipoProducto.id from Actividades as ac where ac.campanas.id = "
               + campania.getId() + " and ac.lotes.id = "+ lote.getId() +"  and   ac.tipoActividad.id = " 
               + tipoActividad.getId() +")";
//       try {
           return getListEnBaseACriterio(hqlQuery);
//       }
//       catch (Exception e) {
//            String errorEn="getFilteredTipoProducto(Campanas campania, Lotes lote, TipoActividad tipoActividad) :\n";
//            Notificaciones.notificar(MENSAJE_ERROR_CONSULTA, errorEn+ e.toString());
//        }
//        return new ArrayList<TipoProducto>();
    }

    @Override
    public List<TipoProducto> getFilteredTipoProducto(Campanas campania, TipoActividad tipoActividad) {
        String hqlQuery = "from TipoProducto tp where tp.id in (select ac.tipoProducto.id from Actividades as ac where ac.campanas.id = "
               + campania.getId() + "  and   ac.tipoActividad.id = " 
               + tipoActividad.getId() +")";
//        try {
            return getListEnBaseACriterio(hqlQuery);
//        }
//        catch (Exception e) {
//             String errorEn="getFilteredTipoProducto(Campanas campania, TipoActividad tipoActividad) :\n";
//            Notificaciones.notificar(MENSAJE_ERROR_CONSULTA, errorEn+ e.toString());
//        }
//        return new ArrayList<TipoProducto>();
    }

    @Override
    public List<Actividades> getFilteredActividades(Campanas campania, Lotes lote, TipoActividad ta, TipoProducto tp) {
        
//        try {
        return getFilteredObjects(Actividades.class, 
                Arrays.asList(
                   Restrictions.eq("campanas", campania),
                   Restrictions.eq("lotes", lote),
                   Restrictions.eq("tipoActividad", ta),
                   Restrictions.eq("tipoProducto", tp)
                ), 
                Order.asc("campanas"),Order.asc("lotes"),Order.asc("tipoActividad"),Order.asc("tipoProducto") );
//        }
//        catch (Exception e) {
//             String errorEn="getFilteredActividades(Campanas campania, Lotes lote, TipoActividad ta, TipoProducto tp) :\n";
//            Notificaciones.notificar(MENSAJE_ERROR_CONSULTA, errorEn+ e.toString());
//        }
//        return new ArrayList<Actividades>();
    }

    @Override
    public List<Actividades> getFilteredActividades(Campanas campania, Lotes lote, TipoActividad ta) {
        
//        try {
            return getFilteredObjects(Actividades.class, 
                Arrays.asList(
                   Restrictions.eq("campanas", campania),
                   Restrictions.eq("lotes", lote),
                   Restrictions.eq("tipoActividad", ta)
                ), 
                Order.asc("campanas"),Order.asc("lotes"),Order.asc("tipoActividad"),Order.asc("tipoProducto") );
//        }
//        catch (Exception e) {
//            String errorEn="getFilteredActividades(Campanas campania, Lotes lote, TipoActividad ta) :\n";
//            Notificaciones.notificar(MENSAJE_ERROR_CONSULTA, errorEn+ e.toString());
//        }
//        return new ArrayList<Actividades>();
        
    }

    @Override
    public List<Estadisticas<Campanas>> getTotales()  {
        ProjectionList proyecciones = Projections.projectionList();
        for (int i = 0 ; i < listaDeProyecciones.getLength() ; i++){
            proyecciones.add(listaDeProyecciones.getProjection(i));
        }
        proyecciones.add(Projections.groupProperty("campanas").as("campoAgrupamiento"));
//        try {
            return  getProjectionListObject(Actividades.class, proyecciones );
//        }
//        catch (Exception e) {
//            String errorEn="getTotales() :\n";
//            Notificaciones.notificar(MENSAJE_ERROR_CONSULTA, errorEn+ e.toString());
//        }
//        return new ArrayList<Estadisticas<Campanas>>();
    }

    @Override
    public Estadisticas<Campanas> getEstadistica(Campanas campania) {
        
        return getEstadistica(campania, null);
        
        
//        final ProjectionList proyecciones = listaDeProyecciones;
//        proyecciones.add(Projections.groupProperty("campanas").as("campoAgrupamiento"));
//        try {
//            return (Estadisticas<Lotes>) GenericManager.getProjectionObject(
//                    Estadisticas.class, Actividades.class, 
////                    listaDeProyecciones, 
//                    proyecciones,
//                    Arrays.asList(Restrictions.eq("campanas", campania))
//                );
//        }
//        catch (Exception e) {
//            Notificaciones.notificar(MENSAJE_ERROR_CONSULTA, e.toString());
//        }
//        return new Estadisticas<Lotes>();
    }

    @Override
    public List<Estadisticas<TipoActividad>> getTotales(Lotes lote) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Estadisticas<Campanas> getEstadistica(Campanas campania, Lotes lote)  {
        
        Estadisticas<Campanas> result;
        List listaRestricciones = new ArrayList<Restrictions>();
        if (campania != null) {
            listaRestricciones.add(Restrictions.eq("campanas", campania));
        }
        if (lote != null ){
            listaRestricciones.add(Restrictions.eq("lotes", lote));
        }
        
//        List listaRestricciones = Arrays.asList(
//                Restrictions.eq("campanas", campania),
//                Restrictions.eq("lotes", lote));
        ProjectionList proyecciones = Projections.projectionList();
        for (int i = 0 ; i < listaDeProyecciones.getLength() ; i++){
            proyecciones.add(listaDeProyecciones.getProjection(i));
        }
        if (campania != null)
            proyecciones.add(Projections.groupProperty("campanas").as("campoAgrupamiento"));
        try {
            
            result =  getProjectionObject(
                    Estadisticas.class, 
                    Actividades.class , 
//                    listaDeProyecciones, 
                    proyecciones,
                    listaRestricciones 
                );
            if (result != null) {
                return result;
            }
        }
        catch (Exception e) {
             String errorEn="getEstadistica(Campanas campania, Lotes lote) :\n";
            Notificaciones.notificar(MENSAJE_ERROR_CONSULTA, errorEn+ e.toString());
        }
        return new Estadisticas();
    }

    @Override
    public List<Estadisticas<Lotes>> getTotales(Campanas campania) {
        
         //Lista de Restricciones
        List listaRestricciones = Arrays.asList(
                Restrictions.eq("campanas", campania));
        //Lista de Proyecciones
        ProjectionList proyecciones = 
                Projections.projectionList()
                .add(Projections.count("id").as("count") )
                .add(Projections.sum("total").as("sum"))
                .add(Projections.avg("total").as("avg"))
                .add(Projections.max("total").as("max"))
                .add(Projections.min("total").as("min"))
                .add(Projections.groupProperty("lotes").as("campoAgrupamiento"));
        
        //Invocar Metodo
//        try {
            return getProjectionListObject(Actividades.class, proyecciones, listaRestricciones);
//        }
//        catch (Exception e) {
//            String errorEn="getTotales(Campanas campania) :\n";
//            Notificaciones.notificar(MENSAJE_ERROR_CONSULTA, errorEn+ e.toString());
//        }
//        return new ArrayList<Estadisticas<Lotes>>();
    }

    @Override
    public List<Estadisticas<TipoActividad>> getTotales(Campanas campania, Lotes lote) {
        //Lista de Restricciones
        List listaRestricciones = Arrays.asList(
                Restrictions.eq("campanas", campania),
                Restrictions.eq("lotes", lote));
        //Lista de Proyecciones
        ProjectionList proyecciones = Projections.projectionList()
//         proyecciones.add(Projections.groupProperty("tipoActividad").as("campoAgrupamiento"));
                .add(Projections.count("id").as("count") )
                .add(Projections.sum("total").as("sum"))
                .add(Projections.avg("total").as("avg"))
                .add(Projections.max("total").as("max"))
                .add(Projections.min("total").as("min"))
                .add(Projections.groupProperty("tipoActividad").as("campoAgrupamiento"));
        
        //Invocar Metodo
//        try {
            return getProjectionListObject(Actividades.class, proyecciones, listaRestricciones);
//        }
//        catch (Exception e) {
//             String errorEn="getTotales(Campanas campania, Lotes lote) :\n";
//            Notificaciones.notificar(MENSAJE_ERROR_CONSULTA, errorEn+ e.toString());
//        }
//        return new ArrayList<Estadisticas<TipoActividad>>();
    }

    @Override
    public List<Estadisticas<TipoProducto>> getTotales(Campanas campania, Lotes lote, TipoActividad tipoActividad) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public List<Estadisticas<TipoActividad>> getTotales(Lotes lote, Date fechaInicio, Date fechaFin) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Estadisticas<Campanas> getEstadistica() {
        Estadisticas<Campanas> result = getEstadistica(null);
        if (result == null) {
            result = new Estadisticas<Campanas>();
        }
        return result;
    }

       
    
}
